package com.zzyl.nursing.service.impl;

import java.util.ArrayList;
import java.util.List;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.zzyl.common.utils.CodeGenerator;
import com.zzyl.common.exception.ServiceException;
import com.zzyl.nursing.domain.*;
import com.zzyl.nursing.dto.CheckInApplyDto;
import com.zzyl.nursing.dto.CheckInElderDto;
import com.zzyl.nursing.mapper.*;
import com.zzyl.nursing.vo.CheckInConfigVo;
import com.zzyl.nursing.vo.CheckInDetailVo;
import com.zzyl.nursing.vo.CheckInElderVo;
import com.zzyl.nursing.vo.ElderFamilyVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.zzyl.nursing.service.ICheckInService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.transaction.annotation.Transactional;

import java.util.Arrays;

/**
 * 入住Service业务层处理
 *
 * @author ruoyi
 * @date 2024-11-11
 */
@Service
public class CheckInServiceImpl extends ServiceImpl<CheckInMapper, CheckIn> implements ICheckInService {
    @Autowired
    private CheckInMapper checkInMapper;
    @Autowired
    private ContractMapper contractMapper;
    @Autowired
    private ElderMapper elderMapper;
    @Autowired
    private BedMapper bedMapper;
    @Autowired
    private CheckInConfigMapper checkInConfigMapper;


    /**
     * 查询入住
     *
     * @param id 入住主键
     * @return 入住
     */
    @Override
    public CheckIn selectCheckInById(Long id) {
        return getById(id);
    }

    /**
     * 查询入住列表
     *
     * @param checkIn 入住
     * @return 入住
     */
    @Override
    public List<CheckIn> selectCheckInList(CheckIn checkIn) {
        return checkInMapper.selectCheckInList(checkIn);
    }

    /**
     * 新增入住
     *
     * @param checkIn 入住
     * @return 结果
     */
    @Override
    public int insertCheckIn(CheckIn checkIn) {
        return save(checkIn) ? 1 : 0;
    }

    /**
     * 修改入住
     *
     * @param checkIn 入住
     * @return 结果
     */
    @Override
    public int updateCheckIn(CheckIn checkIn) {
        return updateById(checkIn) ? 1 : 0;
    }

    /**
     * 批量删除入住
     *
     * @param ids 需要删除的入住主键
     * @return 结果
     */
    @Override
    public int deleteCheckInByIds(Long[] ids) {
        return removeByIds(Arrays.asList(ids)) ? 1 : 0;
    }

    /**
     * 删除入住信息
     *
     * @param id 入住主键
     * @return 结果
     */
    @Override
    public int deleteCheckInById(Long id) {
        return removeById(id) ? 1 : 0;
    }


    /**
     * 申请入住
     *
     * @param dto 入住信息
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void apply(CheckInApplyDto dto) {
        CheckInElderDto old = dto.getCheckInElderDto();
        //校验老人是否已入住
        //首先查询这个老人是否在老人表上有他的身份证信息,再查询他是否是正常状态
        LambdaQueryWrapper<Elder> eldWrapper = new LambdaQueryWrapper<>();
        /*状态（0：禁用，1:启用  2:请假 3:退住中 4入住中 5已退住）*/
        eldWrapper.eq(Elder::getIdCardNo, old.getIdCardNo()).between(Elder::getStatus, 1, 4);
        ;

        Elder elderIn = elderMapper.selectOne(eldWrapper);
        if (elderIn != null) {
            //该老人已入住
            throw new ServiceException("该老人已入住");
        }
        //

        // 更新床位状态为已入住
        Bed bed = bedMapper.selectBedById(dto.getCheckInConfigDto().getBedId());
        if (bed.getBedStatus() == 1) {
            throw new ServiceException("该床位已有人");
        }
        LambdaUpdateWrapper<Bed> bedLambdaUpdateWrapper = new LambdaUpdateWrapper<>();
        bedLambdaUpdateWrapper.set(Bed::getBedStatus, 1).eq(Bed::getBedStatus, 0).eq(Bed::getId, bed.getId());
        int update = bedMapper.update(null, bedLambdaUpdateWrapper);
        /*
         * 不为null时,可以写个bed,实体对象 bed 包含了要更新的数据，这里只设置 status 字段，
         * 其他字段即使在实体对象中未设置也不会被更新。
         *
         * */
        if (update == 0) {
            //等于0说明更新行数为0
            throw new ServiceException("该床位已有人入住");
        }

        //  新增老人
        Elder elder = insertOrUpdate(bed, dto);

        // 新增签约办理(合同)
        insertContract(elder, dto);

        // 新增入住信息
        CheckIn checkIn = insertCheckIn(elder, bed, dto);

        //  新增入住配置
        insertCheckInConfig(checkIn.getId(), dto);

    }

    /**
     * 查询入住信息
     *
     * @param id 通过id查询
     * @return 返回值
     */
    @Override
    public CheckInDetailVo detail(Long id) {

        CheckInDetailVo detailVo = new CheckInDetailVo();
        //获取入住表信息
        CheckIn checkIn = checkInMapper.selectById(id);

        // 查询老人信息

        Elder elder = elderMapper.selectById(checkIn.getElderId());
        CheckInElderVo elderVo = BeanUtil.toBeanIgnoreError(elder, CheckInElderVo.class);
        elderVo.setAge(100);
        detailVo.setCheckInElderVo(elderVo);
        //  查询合同

        LambdaQueryWrapper<Contract> wrapper = new LambdaQueryWrapper<Contract>().
                eq(Contract::getElderId, elder.getId());
        detailVo.setContract(contractMapper.selectOne(wrapper));

        // 查询入住配置
        //  CheckInConfigVo configVo = BeanUtil.toBeanIgnoreError(checkIn, CheckInConfigVo.class);
        LambdaQueryWrapper<CheckInConfig> check = new LambdaQueryWrapper<CheckInConfig>().
                eq(CheckInConfig::getCheckInId, checkIn.getId());
        CheckInConfig checkInConfig = checkInConfigMapper.selectOne(check);

        CheckInConfigVo configVo = BeanUtil.toBeanIgnoreError(checkInConfig, CheckInConfigVo.class);
        configVo.setStartDate(checkIn.getStartDate());
        configVo.setEndDate(checkIn.getEndDate());
        configVo.setBedNumber(checkIn.getBedNumber());
        detailVo.setCheckInConfigVo(configVo);
        // 转换家属列表
        String remark = checkIn.getRemark();
        List<ElderFamilyVo> list = JSONUtil.toList(remark, ElderFamilyVo.class);
        detailVo.setElderFamilyVoList(list);

        // 整合数据返回

        return detailVo;
    }

    /**
     *
     * @param id 老人
     * @return 签订的合同
     */

    /**
     *  老人信息
     * @param id 老人id
     * @return 老人信息
     */
   /* private e getCheckInElderVo(Long id) {
        CheckInElderVo vo = elderMapper.selectCheckInElderVo(id);
        return vo;
    }*/

    /**
     * 添加老人信息
     *
     * @param bed 需要床的床位信息
     * @param dto 传入的信息
     */
    private Elder insertOrUpdate(Bed bed, CheckInApplyDto dto) {
        // 创建并拷贝对象属性值，忽略错误的
       /*
          属性转化
        Elder elder=new Elder();
        BeanUtil.copyProperties(dto.getElder(), elder, false);
        */
        // 类型转换
        Elder elder = BeanUtil.toBeanIgnoreError(dto.getCheckInElderDto(), Elder.class);
        elder.setBedId(bed.getId());
        elder.setBedNumber(bed.getBedNumber());
        elder.setStatus(1);// 启用，申请中
        // 新增
        elderMapper.insert(elder);

        return elder;
    }

    /**
     * 新增签约办理，合同
     *
     * @param elder
     * @param dto
     */
    private void insertContract(Elder elder, CheckInApplyDto dto) {
        String contractNo = "HT" + CodeGenerator.generateContractNumber();
        Contract contract = BeanUtil.toBeanIgnoreError(dto.getCheckInContractDto(), Contract.class);
        contract.setContractNumber(contractNo);
        contract.setElderId(elder.getId());
        contract.setElderName(elder.getName());
        contract.setStatus(0); // 未生效，后期审核与支付后才会生效
        contract.setStartDate(dto.getCheckInConfigDto().getStartDate());
        contract.setEndDate(dto.getCheckInConfigDto().getEndDate());
        contract.setContractName("入住合同");
        //加入表,则对比表里没有的东西
        //需要查询信息,则需要把实体类没有的东西加进去;
        //不过我认为最终还是要看表里的;
        contractMapper.insertContract(contract);
    }

    /**
     * 新增入住信息
     *
     * @param elder 老人信息
     * @param dto   添加的信息
     * @return
     */
    private CheckIn insertCheckIn(Elder elder, Bed bed, CheckInApplyDto dto) {
        CheckIn checkIn = new CheckIn();
        checkIn.setElderName(elder.getName());
        checkIn.setElderId(elder.getId());
        checkIn.setIdCardNo(elder.getIdCardNo());
        checkIn.setStartDate(dto.getCheckInConfigDto().getStartDate());
        checkIn.setEndDate(dto.getCheckInConfigDto().getEndDate());
        checkIn.setNursingLevelName(dto.getCheckInConfigDto().getNursingLevelName());
        checkIn.setRemark(String.valueOf(JSONUtil.parseArray(dto.getElderFamilyDtoList())));
        checkIn.setBedNumber(bed.getBedNumber());
        checkIn.setStatus(0);// 已入住
        save(checkIn);
        return checkIn;
    }

    /**
     * 新增入住配置信息
     *
     * @param id
     * @param dto
     */
    private void insertCheckInConfig(Long id, CheckInApplyDto dto) {
        CheckInConfig config = BeanUtil.toBeanIgnoreError(dto.getCheckInConfigDto(), CheckInConfig.class);
        config.setCheckInId(id);
        checkInConfigMapper.insertCheckInConfig(config);
    }

}
